package com.tuda.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.tuda.common.core.domain.R;
import com.tuda.common.utils.*;
import com.tuda.system.domain.TudaAppletUser;
import com.tuda.system.model.result.LoginUserResult;
import com.tuda.system.model.wx.*;
import com.tuda.system.service.ITudaAppletUserService;
import com.tuda.system.service.IWxDecodeService;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @ClassName WxDecodeServiceImpl
 * @Description TODO
 * @Author Admin
 * @Date 2023/7/17 10:12
 * @Version 1.0
 **/
@Service
public class WxDecodeServiceImpl implements IWxDecodeService {

    private static final Logger logger = LoggerFactory.getLogger(WxDecodeServiceImpl.class);

    @Resource
    private Environment environment;
    @Resource
    private ITudaAppletUserService userService;

    private static final String ACCESS_TOKEN = "accessToken";
    private static final String SESSION_KEY = "sessionKey";
    private static final String UNIONID = "unionid";


    private static final String appId = "wxad2d80a2a54ce004";
    private static final String appSecret = "ec2604fe7562650c51e77a507885b87b";
//    private static final String miniAppId = "wx108d1394a618520b";
//    private static final String miniAppSecret = "3e4671f359438401e79a072b90a260c9";

    private static final String miniAppId = "wx0076a737136b24d3";
    private static final String miniAppSecret = "e9cbe6d9e358c2241403a2743a7f31c7";



    public String getAccessToken(String userId){
        String aToken = (String) RedisUtil.get("wx:accessToken:" + userId);
        if (ToolUtil.isNotEmpty(aToken) && aToken.length() > 10) {
            logger.info(aToken + "---------------------");
            return aToken;
        }else {
            String params = "grant_type=client_credential&appid="+miniAppId+"&secret="+miniAppSecret;
            String info = HttpUtil.sendGet("https://api.weixin.qq.com/cgi-bin/token", params);
            JSONObject json = JSONObject.parseObject(info);
            String accessToken = json.get("access_token").toString();
            RedisUtil.setForTimeS("wx:accessToken:" + userId, accessToken, 6000);
            return  accessToken;
        }
    }

    public R<String> getWxMiniDecodePhone(String code, String userId) {
        if(ToolUtil.isEmpty(userId)){
            userId = "1";
        }
        String phone = "";
        Map<String, Object> wxMap = new HashMap<>();
        wxMap.put("code", code);
        String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token="+getAccessToken(userId);
        logger.info("发送消息内容{}", JSONObject.toJSONString(wxMap));
        String info = HttpUtil.sendPost(url, JSONObject.toJSONString(wxMap));
        JSONObject jsonObject = JSONObject.parseObject(info);
        JSONObject jsonObject1 = (JSONObject) jsonObject.get("phone_info");
//        logger.info(jsonObject.toJSONString() + "/" + jsonObject1.get("purePhoneNumber"));
        logger.info(jsonObject.toJSONString()+"-----------------------------------------");
        if (StringUtils.isBlank(phone)) {
            return R.fail(R.FAIL, "获取失败");
        }
        return R.ok( phone, "获取成功");
    }

    public R getJsApiTicket(String url) {
        Map<String, Object> map = new HashMap<>();
        JSONObject json = null;
        try {
            String wxTicket = (String) RedisUtil.get("wx:ticket:" + url);
            if (ToolUtil.isNotEmpty(wxTicket) && wxTicket.length() > 10) {
                Map<String, Object> keyValue = new Gson().fromJson(wxTicket, Map.class);
                logger.info(keyValue + "---------------------");
                return R.ok(keyValue);
            } else {
                String params = "grant_type=client_credential&appid=" + environment.getProperty("weChat.jsAppId") + "&secret=" + environment.getProperty("weChat.jsAppSecret");
                String info = HttpUtil.sendGet("https://api.weixin.qq.com/cgi-bin/token", params);
                json = JSONObject.parseObject(info);
                String accessToken = json.get("access_token").toString();
                if (ToolUtil.isNotEmpty(accessToken)) {
                    String getTicket = "access_token=" + accessToken + "&type=jsapi";
                    String obj = HttpUtil.sendGet("https://api.weixin.qq.com/cgi-bin/ticket/getticket", getTicket);
                    JSONObject jsonObj = JSONObject.parseObject(obj);
                    logger.info("获取jsapi_ticket:" + jsonObj);
                    String jsapi_ticket = jsonObj.get("ticket").toString();
                    String noncestr = UUID.randomUUID().toString();
                    Long timestamp = System.currentTimeMillis() / 1000;
                    String ps = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url=" + url;
                    String signature = DigestUtils.sha1Hex(com.tuda.common.utils.StringUtils.getContentBytes(ps, "utf-8"));
                    map.put("appId", environment.getProperty("weChat.jsAppId"));
                    map.put("timestamp", timestamp);
                    map.put("nonceStr", noncestr);
                    map.put("signature", signature);
                    String value = new Gson().toJson(map);
                    RedisUtil.setForTimeS("wx:ticket:" + url, value, 6000);
                    return R.ok(map);
                }
            }
        } catch (Exception e) {
            return R.fail("签名验证失败");
        }
        return R.fail("签名验证失败");
    }


    /**
     * 微信小程序登录
     *
     * @param code
     * @return
     */
    public R<AppUserDecodeResult> wxMiniDecode(String code) {
        WeiXinResult result = getMiniSessionKey(code, environment.getProperty("weChat.miniAppId"), environment.getProperty("weChat.miniAppSecret"));
        if (ToolUtil.isNotEmpty(result)) {
            logger.info(new Gson().toJson(result)+"-------获取参数------");
            AppUserWXParam param = new AppUserWXParam();
            param.setWxMiniOpenId(result.getOpenid());
            if(ToolUtil.isNotEmpty(result.getUnionId())){
                param.setUnionId(result.getUnionId());
            }else {
                param.setUnionId(result.getOpenid());
            }
            TudaAppletUser user = userService.loginWeChat(param);
            if (ToolUtil.isOneEmpty(user)) {
                return R.fail("微信小程序授权登录出现错误");
            }
            return R.ok(this.getDecodeResult(user), "微信小程序登录成功");
        }
        return R.fail(R.FAIL, "微信给与用户信息数据出错");
    }

    private static AppUserDecodeResult getDecodeResult(TudaAppletUser user) {
        AppUserDecodeResult decodeResult = new AppUserDecodeResult();
        decodeResult.setHavePhone(ToolUtil.isNotEmpty(user.getPhone()) ? true : false);
        decodeResult.setToken(user.getId().toString());
        decodeResult.setInvalidDate(DateUtils.addDay(7));
        decodeResult.setUserResult(EntityConvertUtils.convertAToB(user, LoginUserResult.class));
        return decodeResult;
    }


    private String getSessionKey(String code, String appid, String secret) {
        String grantType = "authorization_code";
        String params = "appid=" + appid + "&secret=" + secret + "&js_code=" + code + "&grant_type=" + grantType;
        String sr = HttpUtil.sendGet("https://api.weixin.qq.com/sns/jscode2session", params);
        JSONObject json = JSONObject.parseObject(sr);
        String session_key = "";
        if (json.containsKey("errcode")) {
            String errcode = json.get("errcode").toString();
            String errmsg = json.get("errmsg").toString();
            logger.error("得到session_key时解密失败" + errcode + ":" + errmsg);
        }
        try {
            session_key = json.get("session_key").toString();
        } catch (Exception e) {
            logger.warn(e.getMessage());
        }
        return session_key;
    }


    private WeiXinResult getMiniSessionKey(String code, String appid, String secret) {
        WeiXinResult result = new WeiXinResult();
        String grantType = "authorization_code";
        String params = "appid=" + appid + "&secret=" + secret + "&js_code=" + code + "&grant_type=" + grantType;
        String sr = HttpUtil.sendGet("https://api.weixin.qq.com/sns/jscode2session", params);
        JSONObject json = JSONObject.parseObject(sr);
        logger.info("是否包含了用户基础信息:" + json);
        if (json.containsKey("errcode")) {
            String errcode = json.get("errcode").toString();
            String errmsg = json.get("errmsg").toString();
            logger.error("得到session_key时解密失败" + errcode + ":" + errmsg);
        }
        try {
            result.setSessionKey(json.get("session_key").toString());
            result.setOpenid(json.get("openid").toString());
            result.setUnionId(json.get("unionid").toString());
        } catch (Exception e) {
            logger.warn(e.getMessage());
        }
        return result;
    }

}
